package com.gitee.apanlh.util.random;

import com.gitee.apanlh.util.reflection.ClassConvertUtils;

import java.util.concurrent.ThreadLocalRandom;

/**	
 * 	生成验证码
 * 
 * 	@author Pan
 */
public class RandomCodeUtils {
	
	private static final int[] RANDOM_NUM = {
		0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
		9, 8, 7, 6, 5, 4, 3, 2, 1, 0
	};
	private static final int RANDOM_NUM_SIZE = RANDOM_NUM.length;
	
	private static final String[] RANDOM_NUM_STR = {
		"0","1","2","3","4","5","6","7","8","9",
		"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
		"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"
	};
	private static final int RANDOM_NUM_STR_SIZE = RANDOM_NUM_STR.length;
	
	/**
	 * 	构造函数
	 * 
	 * 	@author Pan
	 */
	private RandomCodeUtils() {
		//	不允许外部实例
		super();
	}
	
	/**	
	 * 	默认生成6位 混合随机数
	 * 	
	 * 	@author Pan
	 * 	@return	6位
	 */
	public static String generateMixedRandom() {
		return generateMixed(6);
	}
	
	/**	
	 * 	自定义数量生成
	 * 	<br>混合随机数
	 * 	
	 * 	@author Pan	
	 * 	@param  size	长度
	 * 	@return	String
	 */
	public static String generateMixedRandom(int size) {
		return generateMixed(size);
	}
	
	/**	
	 * 	生成6位数验证码
	 *  
	 * 	@author Pan
	 * 	@return int
	 */
	public static Long generateSixDigitNumber() {
		return ClassConvertUtils.toLong((generate(6)));
	}
	
	/**		
	 * 	生成8位数验证码
	 * 	
	 * 	@author Pan
	 * 	@return	Long	八位整形验证码
	 */
	public static Long generateEightDigitNumber() {
		return ClassConvertUtils.toLong((generate(8)));
	}
	
	/**	
	 * 	不能超过19位数
	 * 	<br>自定义生成位数
	 * 	
	 * 	@author Pan
	 * 	@param  size	长度
	 * 	@return	Long
	 */
	public static Long generateNumber(int size) {
		if (size > 19) {
			throw new NumberFormatException("超过生成验证码最大长度");
		}
		return ClassConvertUtils.toLong((generate(size)));
	}
	
	/**	
	 * 	生成6位验证码
	 * 	
	 * 	@author Pan
	 * 	@return	String
	 */
	public static String generateSixDigitStr() {
		return generate(6);
	}
	
	/**	
	 * 	生成8位验证码
	 * 	
	 * 	@author Pan
	 * 	@return	String
	 */
	public static String generateEightDigitStr() {
		return generate(8);
	}
	
	/**	
	 * 	生成自定义位数验证码
	 * 	<br>可超过19位的验证码
	 * 	
	 * 	@author Pan
	 * 	@param  size	长度
	 * 	@return	String
	 */
	public static String generateStr(String size) {
		return generate(size);
	}
	
	/**	
	 * 	生成自定义位数验证码
	 * 	<br>可超过19位的验证码
	 * 	
	 * 	@author Pan
	 * 	@param  size	长度
	 * 	@return	String
	 */
	public static String generateStr(int size) {
		return generate(size);
	}
	
	/**	
	 *  根据自定义生成规则
	 *  <br>生成自定义的code
	 *  
	 * 	@author Pan
	 * 	@param  arr		规则数组
	 * 	@param  size	长度
	 * 	@return	String
	 */
	public static String generateStr(String[] arr, int size) {
		StringBuilder strBuilder = new StringBuilder(size);
		for (int i = 0, arrLen = arr.length; i < size; i++) {
			strBuilder.append(arr[ThreadLocalRandom.current().nextInt(arrLen)]);
		}
		return strBuilder.toString();
	}
	
	/**	
	 * 	生成随机数方法
	 * 	
	 * 	@author Pan
	 * 	@param  size	长度
	 * 	@return	String
	 */
	private static String generate(Object size) {
		int generateSize;
		
		if (size instanceof String) {
			generateSize = ClassConvertUtils.toInt((String) size);
		} else {
			generateSize = (int) size;
		}
		
		StringBuilder sbBuilder = new StringBuilder(generateSize);
		ThreadLocalRandom randomOfThread = RandomUtils.getRandomOfThread();
		
		for (int i = generateSize; i >= 1; i--) {
			sbBuilder.append(RANDOM_NUM[randomOfThread.nextInt(RANDOM_NUM_SIZE)]);
		}
		return sbBuilder.toString();
	} 
	
	/**	
	 *	生成混合随机数
	 *	<br>0-9 a-z A-z
	 *	
	 *  @author Pan
	 * 	@param  size	长度
	 * 	@return	String
	 */
	private static String generateMixed(int size) {
		StringBuilder strBuilder = new StringBuilder(size);
		ThreadLocalRandom randomOfThread = RandomUtils.getRandomOfThread();
		
		for (int i = 0; i < size; i++) {
			strBuilder.append(RANDOM_NUM_STR[randomOfThread.nextInt(RANDOM_NUM_STR_SIZE)]);
		}
		return strBuilder.toString();
	}
}
